/**
 * Modules to control application life and create native browser window
 */
const { app, BrowserWindow, Menu, ipcMain, Notification } = require('electron')
const path = require('path')
const fs = require('fs')
let mainWindow = {}
makeSingleInstance()

let imageStreamList = []      // 所有图片流数据
let allFilesNum = 0           // 所有要下载文件的数量
let doneFilesNum = 0          // 已下载的文件数量
let successFilesNum = 0       // 下载成功的文件数量

function createWindow () {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1400,
    height: 780,
    minWidth: 1000,
    minHeight: 500,
    icon: path.join(__dirname, 'icon.ico'),
    // backgroundColor: '#000',
    // fullscreen: true,
    frame: false,     // 去掉顶部导航
    webPreferences: {
      nodeIntegration: true,    // 访客页是否集成node，默认是false
      preload: path.join(__dirname, 'renderer.js'),      // 在页面运行其他脚本之前预先加载指定的脚本 无论页面是否集成Node, 此脚本都可以访问所有Node API 脚本路径为文件的绝对路径。 当 node integration 关闭时, 预加载的脚本将从全局范围重新引入node的全局引用标志
      enableRemoteModule: true,           // 是否开启允许远程模块，默认是false
    }
  })
  // and load the index.html of the app.
  // mainWindow.loadFile('web/index.html')
  mainWindow.loadURL('http://192.168.2.30:9000')
  // mainWindow.loadURL('http://58.213.152.154:8504/GMP/index.html')

  // Open the DevTools.
  mainWindow.webContents.openDevTools()

  /**
   * 必须要在渲染进程的页面加载完了之后再触发，否则发送不生效，所以要监听did-finish-load
   */
  mainWindow.webContents.on('did-finish-load', () => {
    // 主进程主动给渲染进程发送数据
    let pathStr = path.resolve('', './config.json')
    let fileDir = path.resolve('', 'file')
    let configData = {}
    try {
      configData = JSON.parse(fs.readFileSync(pathStr, 'utf8'))
    } catch (e) {
      notification('error', '缺少config.json配置文件')
      return
    }    
    mainWindow.webContents.send('getConfigData', configData)
    // 获取config.json里所有文件id
    let fileList = getFileIdList(configData)
    allFilesNum = fileList.length
    /**
     * 判断根目录下是否有file文件夹，没有的话就新建一个，有的话就将文件夹里图片资源发给渲染进程
     */
    if (!isExistDir(fileDir)) {       
      fs.mkdirSync(fileDir)
      downloadFiles(fileList)
    } else {
      fs.readdirSync(fileDir).forEach(item => {
        if(!item.endsWith('.exe')) {
          imageStreamList.push({
            id: item.split('.')[0],
            stream: fs.readFileSync(path.resolve('./file', item)),
            type: item.split('.')[1]
          })
        }
      })
      mainWindow.webContents.send('getImageStream', imageStreamList)
    }
  })
}

/**
 * 创建通知
 */
function notification (type, message) {
  let icon = null
  switch (type) {
    case 'success':
      icon = './success-icon.png'
      break;
    case 'warning':
      icon = './warning-icon.png'
      break;
    case 'error':
      icon = './error-icon.png'
      break;
    default:
      icon = './warning-icon.png'
      break;
  }
  app.setAppUserModelId(new Date().toLocaleTimeString())
  let notice = new Notification({
    // 通知的标题, 将在通知窗口的顶部显示
    // title: '虚拟仿真平台通知',
    // 通知的正文文本, 将显示在标题或副标题下面
    body: message,
    // false有声音，true没声音
    silent: false,
    icon,
    // 通知的超时持续时间 'default' or 'never'
    timeoutType: 'default',
  })
  notice.show()
}

/*隐藏electron创听的菜单栏*/
// Menu.setApplicationMenu(null)

/**
 * This method will be called when Electron has finished
 * initialization and is ready to create browser windows.
 * Some APIs can only be used after this event occurs.
 */
app.whenReady().then(() => {
  createWindow()
  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
}).then(() => {
  // notification('welcome to use GMP')      // 通知必须在app ready之后执行
})

/**
 * Quit when all windows are closed, except on macOS. There, it's common
 * for applications and their menu bar to stay active until the user quits
 * explicitly with Cmd + Q.
 */
app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit()
})

/**
 * Make this app a single instance app.
 * 
 * The main window will be restored and focused instead of a second window
 * opened when a person attempts to launch a second instance.
 * 
 * Returns true if the current version of the app should quit instead of launching.
 */
function makeSingleInstance () {
  if (process.mas) return

  app.requestSingleInstanceLock()

  app.on('second-instance', () => {
    if (mainWindow) {
      if (mainWindow.isMinimized()) mainWindow.restore()
      mainWindow.focus()
    }
  })
}

/**
 * In this file you can include the rest of your app's specific main process
 * code. You can also put them in separate files and require them here.
 */


// 获取config.json里所有的fileId
function getFileIdList (configData) {
  let objs = []
  configData.zsk.forEach(item => {
    objs = objs.concat(item.resources)
  })
  configData.fzxl.forEach(item => {
    objs = objs.concat(item.resources)
  })
  configData.fztk.forEach(item => {
    objs = objs.concat(item)
  })
  let targetList = []
  objs.forEach(item => {
    item.fid ? targetList.push(item.fid) : ''
    item.logoId ? targetList.push(item.logoId) : ''
  })
  return targetList
}

// 判断指定目录是否存在
function isExistDir (path, dirname) {
  try {
    return fs.statSync(path, dirname).isDirectory()
  } catch (e) {
    return false
  }
}

// 批量下载文件
const { downloadUrlPrefix }  = require('./env')
function downloadFiles (fileIdList) {
  fileIdList.forEach(item => {
    mainWindow.webContents.downloadURL(downloadUrlPrefix + item)
  })
  // 监听下载的回调函数
  mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
    // 设置文件存放位置
    item.setSavePath(path.resolve('', 'file', item.getFilename()))
    item.once('done', (event, state) => {
      doneFilesNum ++
      if(state === 'completed') {
        successFilesNum ++
        if(item.getMimeType().startsWith('image/')) {
          imageStreamList.push({
            id: item.getFilename().split('.')[0],
            stream: fs.readFileSync(path.resolve('./file', item.getFilename())),
            type: item.getFilename().split('.')[1],
          })
          mainWindow.webContents.send('getImageStream', imageStreamList)
        }
      } else {
        notification('error', `${item.getFilename()}文件下载失败`)
      }
      console.log(successFilesNum, doneFilesNum, allFilesNum)
      doneFilesNum === allFilesNum ? mainWindow.setProgressBar(0) : mainWindow.setProgressBar(doneFilesNum / allFilesNum)      
      mainWindow.webContents.send('download-progress', {successFilesNum, doneFilesNum, allFilesNum})
    })
  })
}



/**
 * 主进程与渲染进程通信
 */

// 窗口最小化
ipcMain.on('window-min', (event, arg) => {
  mainWindow.minimize()
})
// 窗口最大化
ipcMain.on('window-max', (event, arg) => {
  if (mainWindow.isMaximized()) {
    mainWindow.restore()
  } else {
    mainWindow.maximize()
  }
})
// 关闭窗口
ipcMain.on('window-close', (event, arg) => {
  console.log('click close')
  app.quit()
})
// 打开exe
ipcMain.on('openExe', (event, arg) => {
  const exec = require("child_process").exec;
  let workerProcess = exec(path.resolve('', 'file', `${arg}.exe -pb5ly1YZ6#bOaw_#w`))
  workerProcess.stdout.on('data', function (data) {
    console.log('stdout data:' + data)
  })
  workerProcess.stderr.on('data', function (data) {
    notification('error', '打开仿真程序失败')
  })
  workerProcess.on('close', function (code) {
    console.log('u3d closed')
  })
  // exec(path.resolve('', 'file', `${arg}.exe -pb5ly1YZ6#bOaw_#w`), (error, stdout, stderr) => {
  //   console.log('stdout:' + arg)
  //   // mainWindow.webContents.send('test-msg', {stdout, stderr, error})
  // });
})
// 消息通知
ipcMain.on('open-notification', (event, arg) => {
  notification(arg.type, arg.message)
})





// var ps = require('current-process');
// ps.get(function(err, processes) {
//   console.log(processes)
// })